package cn.lpq.one_qrcode_pay.controller;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.egzosn.pay.common.api.PayMessageInterceptor;
import com.egzosn.pay.common.util.DateUtils;
import com.egzosn.pay.common.util.sign.SignUtils;
import com.egzosn.pay.spring.boot.core.PayServiceManager;
import com.egzosn.pay.spring.boot.core.bean.MerchantPayOrder;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import cn.lpq.one_qrcode_pay.model.WechatPayDetail;
import cn.lpq.one_qrcode_pay.pojo.WxPayProperty;
import cn.lpq.one_qrcode_pay.service.WechatPayDetailService;
import cn.lpq.one_qrcode_pay.util.Img2Base64Util;
import cn.lpq.one_qrcode_pay.util.PrimaryKeyRedisUtil;
import cn.lpq.one_qrcode_pay.util.QRCodeUtil;
import cn.lpq.one_qrcode_pay.util.StringUtils;
import lombok.extern.slf4j.Slf4j;

@RestController
@Slf4j
public class PayDemoController {

	@Resource
	private WechatPayDetailService thisService;

	// 收款方名称
	private static final String receiveName = "中共湖南省委党校湖南行政学院";

	String access_token;

	String jsapiTicket;

	@Autowired
	private PrimaryKeyRedisUtil keyRedisUtil;

	@Autowired
	private PayServiceManager manager;

	@Autowired
	private WxPayProperty wxPayProperty;

	@Scheduled(fixedDelay = 7100 * 1000)
	public void init() {
		refreshAccessToken();
		refreshJsapiTicket();
	}

	@ResponseBody
	@RequestMapping(value = "/PayDemo/qrCode")
	public Map<String, Object> name(WechatPayDetail payDetail) {
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			// detailsId是MerchantPayServiceConfigurer注册支付配置时配置的id
			String detailsId = "2";
			// com.egzosn.pay.common.bean.TransactionType
			String wayTrade = "NATIVE";
			Map<String, Object> addition = new HashMap<String, Object>();
			addition.put("callBackUrl", payDetail.getCallBackUrl());
			payDetail.setCustSn(keyRedisUtil.getId(WechatPayDetail.ModuleType));
			MerchantPayOrder payOrder = new MerchantPayOrder(detailsId, wayTrade, payDetail.getTitle(), "摘要",
					payDetail.getAmount(), payDetail.getCustSn());
			payOrder.setAddition(JSONObject.toJSONString(addition));

			// 存放在二维码中的内容
			String text = manager.getQrPay(payOrder);
			// 嵌入二维码的图片路径
			String imgPath = wxPayProperty.getQrCodeEmbed();
			// 生成的二维码的路径及名称
			String destPath = wxPayProperty.getQrCodeDir() + "/"
					+ DateUtils.formatDate(new Date(), "yyyy/MM/dd/HHmmssSSS-") + payDetail.getAmount() + ".jpg";
			// 生成二维码
			QRCodeUtil.encode(text, imgPath, destPath, true);
			payDetail.setDealType("24700");
			if (!StringUtils.isEmpty(payDetail.getMobile())) {
				payDetail.setMobile(Base64.decodeStr(payDetail.getMobile()));
			}
			boolean flag = thisService.save(payDetail);
			if (flag) {
				result.put("code", "0");
				result.put("message", "生成成功");
				result.put("success", true);
				result.put("data", Img2Base64Util.getImgStr(destPath));
			} else {
				result.put("code", "1");
				result.put("message", "微信支付流水记录保存失败");
				result.put("success", false);
				result.put("data", null);
			}
		} catch (Exception e) {
			result.put("code", "1");
			result.put("message", "生成失败：" + e.getMessage());
			result.put("success", false);
			result.put("data", null);
			log.error("支付二维码生成失败", e);
		}
		return result;
	}

	/**
	 * 支付宝支付可以用直接生成出的html支付<br>
	 * 微信需要获取用户信息(code,openid),然后生成预订单,交给JS去唤起支付
	 * 
	 * @param request
	 * @param amount
	 * @param timestamp
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/PayDemo/toPay.html", produces = "text/html;charset=UTF-8")
	public String toPay(HttpServletRequest request, WechatPayDetail payDetail) {
		payDetail.setTitle(URLUtil.decode(payDetail.getTitle()));
		payDetail.setName(URLUtil.decode(payDetail.getName()));
		payDetail.setDeptName(URLUtil.decode(payDetail.getDeptName()));
		log.info(JSONUtil.toJsonStr(payDetail));
		// 识别userAgent区分使用的是微信还是支付宝
		String userAgent = request.getHeader("user-agent");

		payDetail.setCustSn(keyRedisUtil.getId(WechatPayDetail.ModuleType));
		if (!StringUtils.isEmpty(payDetail.getMobile())) {
			payDetail.setMobile(Base64.decodeStr(payDetail.getMobile()));
		}
		thisService.save(payDetail);

		// detailsId是MerchantPayServiceConfigurer注册支付配置时配置的id
		String detailsId;

		// com.egzosn.pay.common.bean.TransactionType
		String wayTrade;
		String payHtml;

		Map<String, Object> addition = new HashMap<String, Object>();
		addition.put("callBackUrl", payDetail.getCallBackUrl());
		
//		if ((userAgent != null) && userAgent.contains("AlipayClient")) {
//			log.info("当前使用的是支付宝");
//			// AliTransactionType
//			detailsId = "1";
//			wayTrade = "WAP";
//
//			MerchantPayOrder payOrder = new MerchantPayOrder(detailsId, wayTrade, payDetail.getTitle(), "摘要",
//					payDetail.getAmount(), payDetail.getCustSn());
//			payOrder.setAddition(JSONObject.toJSONString(addition));
//			payHtml = manager.toPay(payOrder);
//		} else 
		if ((userAgent != null) && userAgent.contains("wxwork")) {
			log.info("当前使用的是企业微信");
			// WxTransactionType
			detailsId = "2";
			if ("24800".equals(payDetail.getDealType())) {
				detailsId="3";
			}
			
			wayTrade = "MWEB";

			MerchantPayOrder payOrder = new MerchantPayOrder(detailsId, wayTrade, payDetail.getTitle(), "摘要",
					payDetail.getAmount(), payDetail.getCustSn());
			payOrder.setAddition(JSONObject.toJSONString(addition));
			payHtml = manager.toPay(payOrder);
//			detailsId = "2";
//			wayTrade = "JSAPI";
//
//			long timestamp = System.currentTimeMillis() / 1000;
//			String noncestr = RandomUtil.randomString(16);
//			String signature = SignUtils.SHA1.createSign("jsapi_ticket=" + jsapiTicket + "&noncestr=" + noncestr
//					+ "&timestamp=" + timestamp + "&url=" + wxPayProperty.getDomain() + "/PayDemo/toPay.html?amount="
//					+ payDetail.getAmount() + "&callBackUrl=" + payDetail.getCallBackUrl(), "", "utf-8");
//
//			MerchantPayOrder payOrder = new MerchantPayOrder(detailsId, wayTrade, payDetail.getTitle(), "摘要",
//					payDetail.getAmount(), payDetail.getCustSn());
//			payOrder.setOpenid("oX02Ev6uiVWtIPcHs4Y8jxuKxeVI");
//			payOrder.setAddition(JSONObject.toJSONString(addition));
//			// 产生预订单
//			Map<String, Object> map = manager.getOrderInfo(payOrder);
//			// 交给微信唤起支付
//			payHtml = "<script src='https://res2.wx.qq.com/open/js/jweixin-1.4.0.js'></script>\r\n"
//					+ "<script>setTimeout(function(){wx.config({\r\n" + "    debug: true,\r\n" + "    appId: '"
//					+ wxPayProperty.getAppid() + "',\r\n" + "    timestamp:'" + timestamp + "' ,\r\n"
//					+ "    nonceStr: '" + noncestr + "',\r\n" + "    signature: '" + signature + "',\r\n"
//					+ "    jsApiList: ['chooseWXPay']\r\n" + "});" + "wx.ready(function() {\r\n"
//					+ "    wx.checkJsApi({\r\n" + "        jsApiList: ['chooseWXPay'],\r\n"
//					+ "        success: function(res) {}\r\n" + "    });\r\n" + "    wx.chooseWXPay({\r\n"
//					+ "        timestamp: '" + map.get("timeStamp") + "',\r\n" + "        nonceStr: '"
//					+ map.get("nonceStr") + "',\r\n" + "        package: '" + map.get("package") + "',\r\n"
//					+ "        signType: '" + map.get("signType") + "',\r\n" + "        paySign: '" + map.get("sign")
//					+ "',\r\n" + "        success: function(res) {\r\n" + "            alert('支付成功');\r\n"
//					+ "        }\r\n" + "    });\r\n" + "})}, 1000);</script>";
		} else if ((userAgent != null) && userAgent.contains("MicroMessenger")) {
			log.info("当前使用的是微信");
			// WxTransactionType
			detailsId = "2";
			if ("24800".equals(payDetail.getDealType())) {
				detailsId="3";
			}
			wayTrade = "JSAPI";

			// 使用userid去企业微信换openid
			String userid = request.getParameter("userid");
			userid = URLUtil.decode(userid);
			log.info("获取到的userid：" + userid);
			
			String json = HttpUtil
					.createPost(
							"https://qyapi.weixin.qq.com/cgi-bin/user/convert_to_openid?access_token=" + access_token)
					.body(new cn.hutool.json.JSONObject().put("userid", userid)).execute().body();
			log.info(userid + "userid转换后" + json);
			String openid = JSONUtil.parseObj(json).getStr("openid");
			

			MerchantPayOrder payOrder = new MerchantPayOrder(detailsId, wayTrade, payDetail.getTitle(), "摘要",
					payDetail.getAmount(), payDetail.getCustSn());
			payOrder.setOpenid(openid);
			payOrder.setAddition(JSONObject.toJSONString(addition));
			// 产生预订单
			Map<String, Object> map = manager.getOrderInfo(payOrder);
			// 交给微信唤起支付
			payHtml = "<script>function onBridgeReady() {\r\n"
					+ "    WeixinJSBridge.invoke('getBrandWCPayRequest', {\r\n" + "        \"appId\": \""
					+ map.get("appId") + "\",\r\n" + "        \"timeStamp\": \"" + map.get("timeStamp") + "\",\r\n"
					+ "        \"nonceStr\": \"" + map.get("nonceStr") + "\",\r\n" + "        \"package\": \""
					+ map.get("package") + "\",\r\n" + "        \"signType\": \"MD5\",\r\n" + "        \"paySign\": \""
					+ map.get("sign") + "\"\r\n" + "    }, function(res) {\r\n"
					+ "        if (res.err_msg == \"get_brand_wcpay_request:ok\") { alert('支付成功！');}else {\r\n"
					+ "                            alert('支付失败：' + res.err_msg);\r\n" + "                        }\r\n"
					+ "                        WeixinJSBridge.call('closeWindow');\r\n" + "    });\r\n" + "}\r\n"
					+ "if (typeof WeixinJSBridge == \"undefined\") {\r\n" + "    if (document.addEventListener) {\r\n"
					+ "        document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);\r\n"
					+ "    } else if (document.attachEvent) {\r\n"
					+ "        document.attachEvent('WeixinJSBridgeReady', onBridgeReady);\r\n"
					+ "        document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);\r\n" + "    }\r\n"
					+ "} else {\r\n" + "    onBridgeReady();\r\n" + "}</script>";
		} else {
			detailsId = "2";
			wayTrade = "MWEB";

			MerchantPayOrder payOrder = new MerchantPayOrder(detailsId, wayTrade, payDetail.getTitle(), "摘要",
					payDetail.getAmount(), payDetail.getCustSn());
			payOrder.setAddition(JSONObject.toJSONString(addition));
			payHtml = manager.toPay(payOrder);
		}

		String html = "<!DOCTYPE HTML><html><head><meta charset='htf-8' /><meta name='viewport' content='width=device-width, initial-scale=1.0'/><title>YC支付中心</title><style> body{font-family: 'Microsoft YaHei';} #amount,#error{height: 80px; line-height: 80px; text-align: center; color: #f00; font-size: 30px; font-weight: bold;} #error{font-size: 20px;} #info{padding: 0 10px; font-size: 12px;} table{width: 100%; border-collapse: collapse;} tr{border: 1px solid #ddd;} td{padding: 10px;} .fr{text-align: right; font-weight: bold;}</style><script src='//cdn.jsdelivr.net/jquery/1.12.1/jquery.min.js'></script></head><body><div id='amount'>¥ "
				+ payDetail.getAmount() + "</div><div id='info'><table><tr><td>购买商品</td><td class='fr'>"
				+ payDetail.getTitle() + "</td></tr><tr><td>收款方</td><td class='fr'>" + receiveName
				+ "</td></tr></table></div>";
		html += payHtml + "</body></html>";

		return html;
	}

	/**
	 * 支付回调地址
	 *
	 * @param request   请求
	 * @param detailsId 列表id
	 * @return 支付是否成功
	 * @throws IOException IOException 拦截器相关增加，
	 *                     详情查看{@link com.egzosn.pay.common.api.PayService#addPayMessageInterceptor(PayMessageInterceptor)}
	 *                     <p>
	 *                     业务处理在对应的PayMessageHandler里面处理，在哪里设置PayMessageHandler，详情查看{@link com.egzosn.pay.common.api.PayService#setPayMessageHandler(com.egzosn.pay.common.api.PayMessageHandler)}
	 *                     </p>
	 *                     如果未设置 {@link com.egzosn.pay.common.api.PayMessageHandler}
	 *                     那么会使用默认的
	 *                     {@link com.egzosn.pay.common.api.DefaultPayMessageHandler}
	 */
	@RequestMapping(value = "/PayDemo/payBack{detailsId}.json")
	public String payBack(HttpServletRequest request, @PathVariable String detailsId) throws IOException {
		// 业务处理在对应的PayMessageHandler里面处理，在哪里设置PayMessageHandler，详情查看com.egzosn.pay.common.api.PayService.setPayMessageHandler()
		return manager.payBack(detailsId, request.getParameterMap(), request.getInputStream());
	}

	@RequestMapping(value = "/")
	public void index(HttpServletResponse response) throws IOException {
		response.sendRedirect("index.html");
	}

	public String refreshAccessToken() {
		String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + wxPayProperty.getAppid() + "&corpsecret="
				+ wxPayProperty.getAppSecret();
		String result = HttpUtil.get(url);
		access_token = JSONUtil.parseObj(result).getStr("access_token");
		return access_token;
	}

	public String refreshJsapiTicket() {
		String url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=" + access_token;
		String result = HttpUtil.get(url);
		jsapiTicket = JSONUtil.parseObj(result).getStr("ticket");
		return jsapiTicket;
	}
}
